package com.okq.util.security;

import com.okq.entity.*;
import com.okq.service.*;
import com.okq.util.PublicClass;
import com.okq.util.TimeTool;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

/**
 * 描述 : Spring Security框架登陆验证类
 * 登陆失败时需要在session里面添加loginFailure属性表示失败原因,然后就可以在登陆页面通过request获取loginFailure
 * 作者 : zdl
 * 日期 : 2017/3/15 13:26
 */
public class UserDetailServiceImpl implements UserDetailsService {
    /**
     * 人员接口
     */
    @Autowired
    private IUserService userServiceImpl;
    /**
     * 菜单接口
     */
    @Autowired
    private IMenuService menuServiceImpl;
    /**
     * 角色接口
     */
    @Autowired
    private IRoleService roleServiceImpl;
    /**
     * 公司接口
     */
    @Autowired
    private ICompanyService companyServiceImpl;
    /**
     * 部门接口
     */
    @Autowired
    private IGroupService groupServiceImpl;
    /**
     * 加载菜单
     */
    @Resource(name = "securityMetadataSource")
    private SecurityMetadataSource dataSource;
    /**
     * 系统日志接口
     */
    @Autowired
    private ILogService logServiceImpl;

    /**
     * 日志
     */
    private static final Logger logger = Logger.getLogger(UserDetailServiceImpl.class);

    @Override
    public UserDetails loadUserByUsername(String loginName) throws UsernameNotFoundException, DataAccessException {
        // 获取请求
        ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
        HttpServletRequest request = attr.getRequest();
        request.getSession().setAttribute("loginFailure", null); // 清空session保存的登录失败原因
        if (loginName == null) {
            request.getSession().setAttribute("loginFailure", "failure"); // 登陆失败
        } else {
            try {
                User user = userServiceImpl.getUserByLoginName(loginName);
                if (user == null) {
                    request.getSession().setAttribute("loginFailure", "loginNameError");// 登录名不存在
                } else {
                    // 给该用户添加授权模块
                    List<GrantedAuthority> authsList = new ArrayList<>();
                    Group group = groupServiceImpl.getGroupById(user.getGroupId());
                    if (group != null) {
                        request.getSession().setAttribute("group", group);// 把部门列表存放到session
                        Company company = companyServiceImpl.getCompanyById(group.getCompanyId());
                        request.getSession().setAttribute("company", company);// 把单位列表存放到session
                        dataSource.loadResourceDefine();// 加载模块列表
                        Role role = roleServiceImpl.getRoleById(user.getRoleId());
                        if (role != null) {
                            List<Menu> menuList = menuServiceImpl.listMenuByRoleId(role.getId());
                            request.getSession().setAttribute("menuList", menuList);// 把菜单列表存放到session
                            if (menuList != null && !menuList.isEmpty() && menuList.size() > 0) {
                                for (Menu menu : menuList) {
                                    authsList.add(new GrantedAuthorityImpl(menu.getMenuCode())); // 保存菜单代码
                                }
                            }
                        }
                    }
                    request.getSession().setAttribute("loginUser", user);// 登录信息保存在Session
                    String nowTime = TimeTool.getNowTime();
                    user.setLastloginTime(Timestamp.valueOf(nowTime));
                    userServiceImpl.updateUser(user);
                    String userName = user.getUserName();
                    String content = "用户：" + userName + "，于" + nowTime + " 登录到后台管理系统！";
                    PublicClass.addLog(userName, user.getLoginName(), "登录页", 1, content, logServiceImpl);
                    return new org.springframework.security.core.userdetails.User(
                            user.getLoginName(), user.getLoginPass(), true, true, true, true, authsList);
                }
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
            }
        }

        return null;
    }

}
